//
//  Font+Extension.swift
//  MyWidgets
//
//  Created by Max Mg on 2023/8/13.
//

import Foundation
import UIKit
import WidgetKit
import SwiftUI

public typealias FontName = String

public extension FontName {
    static let PingFangSC           = "PingFangSC"
    static let Damion               = "Damion"
    
    /// 默认可编辑的字体
    static let allNames: [FontName] = [
        .PingFangSC, .Damion
    ]
    
    // 等宽字体
    static let monospaceFonts: [FontName] = {
        []
    }()
    
    func font(_ size: CGFloat, weight: Font.Weight = .regular) -> Font {
        return Font.font(self, size: size, weight: weight)
    }
}

public extension UIFont {
    class func font(name: FontName, size: CGFloat, weight: UIFont.Weight = .regular) -> UIFont {
        guard !name.isEmpty,
                let _ = UIFont(name: name, size: size) else {
            return UIFont.systemFont(ofSize: size, weight: weight)
        }
        var finalFontName = name
        
        let fontNames = UIFont.fontNames(forFamilyName: name)
        switch weight {
        case .light:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-light") || $0.lowercased().hasSuffix("_light") }) {
                finalFontName = aName
            }
        case .medium:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-medium") || $0.lowercased().hasSuffix("_medium") }) {
                finalFontName = aName
            }
        case .bold:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-bold") || $0.lowercased().hasSuffix("_bold") }) {
                finalFontName = aName
            }
        case .semibold:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-semibold") || $0.lowercased().hasSuffix("_semibold") }) {
                finalFontName = aName
            }
        case .heavy:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-heavy") || $0.lowercased().hasSuffix("_heavy") }) {
                finalFontName = aName
            }
        case .black:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-black") || $0.lowercased().hasSuffix("_black") }) {
                finalFontName = aName
            }
        default:
            break
        }
        
        return UIFont(name: finalFontName, size: size)!
    }
}

public extension Font {
    
    static func font(_ name: String?, size: CGFloat, weight: Font.Weight = .regular) -> Font {
        guard let name = name, !name.isEmpty,
                let _ = UIFont(name: name, size: size) else {
            return Font.system(size: size, weight: weight)
        }
        var finalFontName = name
        
        let fontNames = UIFont.fontNames(forFamilyName: name)
        switch weight {
        case .light:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-light") || $0.lowercased().hasSuffix("_light") }) {
                finalFontName = aName
            }
        case .medium:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-medium") || $0.lowercased().hasSuffix("_medium") }) {
                finalFontName = aName
            }
        case .bold:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-bold") || $0.lowercased().hasSuffix("_bold") }) {
                finalFontName = aName
            }
        case .semibold:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-semibold") || $0.lowercased().hasSuffix("_semibold") }) {
                finalFontName = aName
            }
        case .heavy:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-heavy") || $0.lowercased().hasSuffix("_heavy") }) {
                finalFontName = aName
            }
        case .black:
            if let aName = fontNames.first(where: { $0.lowercased().hasSuffix("-black") || $0.lowercased().hasSuffix("_black") }) {
                finalFontName = aName
            }
        default:
            break
        }
        
        return Font.custom(finalFontName, size: size)
    }
}

